package com.atmilan.quartz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.atmilan.quartz.utils.product.BuyerProductUtil;
import com.atmilan.quartz.utils.product.EuropeProductUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.model.dto.buyer.BuyerProductResDTO;
import com.atmilan.quartz.model.dto.buyer.BuyerProductResDTO.Product;
import com.atmilan.quartz.model.dto.buyer.BuyerProductResDTO.ProductSku;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.entity.buyer.BuyerProduct;
import com.atmilan.quartz.model.entity.buyer.BuyerProductSku;
import com.atmilan.quartz.model.entity.buyer.BuyerProductSkuMerged;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.StoreProductAttr;
import com.atmilan.quartz.model.entity.crmeb.StoreProductAttrResult;
import com.atmilan.quartz.model.entity.crmeb.StoreProductAttrValue;
import com.atmilan.quartz.model.entity.crmeb.StoreProductDescription;
import com.atmilan.quartz.model.entity.europe.EuropeBrand;
import com.atmilan.quartz.model.entity.europe.EuropeProduct;
import com.atmilan.quartz.service.IProductService;
import com.atmilan.quartz.service.IStoreProductAttrResultService;
import com.atmilan.quartz.service.IStoreProductAttrService;
import com.atmilan.quartz.service.IStoreProductAttrValueService;
import com.atmilan.quartz.service.IStoreProductDescriptionService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemAttachmentService;
import com.atmilan.quartz.sync.pull.buyer.converter.BaseBuyerProductConverter;
import com.atmilan.quartz.sync.pull.buyer.converter.BaseBuyerSkuConverter;
import com.atmilan.quartz.sync.pull.europe.service.IEuropeBrandService;
import com.atmilan.quartz.sync.push.crmeb.domain.StoreProductAttrValueRequest;
import com.atmilan.quartz.utils.source.SourceBuyerProductUtil;
import com.atmilan.quartz.utils.source.SourceEuropeProductUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author muyu
 * @date 2020-09-01
 */
@Slf4j
@Service
public class ProductServiceImpl implements IProductService {

    @Autowired
    IEuropeBrandService europeBrandService;
    @Autowired
    SourceEuropeProductUtil sourceEuropeProductUtil;
    @Autowired
    SourceBuyerProductUtil sourceBuyerProductUtil;
    @Autowired
    BaseBuyerProductConverter baseBuyerProductConverter;
    @Autowired
    BaseBuyerSkuConverter baseBuyerSkuConverter;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    IStoreProductAttrService storeProductAttrService;
    @Autowired
    IStoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    IStoreProductAttrResultService storeProductAttrResultService;
    @Autowired
    IStoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private ISystemAttachmentService systemAttachmentService;
    @Autowired
    BuyerProductUtil buyerProductUtil;
    @Autowired
    EuropeProductUtil europeProductUtil;

    /**
     * 实时更新商品数据
     * @Description:  
     * @author daigb 
     * @param @param storeProduct
     * @return void
     * @throws
     */
    @Override
    public String updateProductByNow(StoreProduct storeProduct) {
        String barCode = storeProduct.getBarCode();
        try {
            // buyer商品
            if (ProductTypeEnum.valueOf(storeProduct.getIsEurope()) == ProductTypeEnum.BUYER) {
                BuyerProductResDTO buyerProductResDTO = buyerProductUtil.getBuyerProductByBarCode(barCode);
                // 处理主表数据
                List<Product> buyerProducts = buyerProductResDTO.getProduct();
                if (CollectionUtils.isEmpty(buyerProducts)) {
                    // log.info("--------------- 实时查询buyer商品, 未取到数据, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                Product buyerProductDTO = buyerProducts.get(0);
                // 金额不对时商品下架
                if (Integer.parseInt(buyerProductDTO.getSalePrice()) <= 0) {
                    // log.info("--------------- 实时查询buyer商品, 商品金额不是正常值, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                // 不可售商品下架
                if (0 == buyerProductDTO.getOnSale()) {
                    // log.info("--------------- 实时查询buyer商品, 商品金额不是正常值, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                // 去除sku信息过滤库存为0的
                int stock = 0;
                List<ProductSku> buyerSkus = buyerProductDTO.getSkus();
                List<ProductSku> productSkus = new ArrayList<ProductSku>();
                for (ProductSku sku : buyerSkus) {
                    if (0 < sku.getStock()) {
                        stock += sku.getStock();
                        productSkus.add(sku);
                    }
                }
                // 没有规格时商品下架
                if (CollectionUtils.isEmpty(productSkus)) {
                    // log.info("--------------- 实时查询buyer商品, 商品没有正常库存规格, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                BuyerProduct buyerProduct = baseBuyerProductConverter.toModel(buyerProductDTO);
                List<BuyerProductSku> buyerProductSkus = baseBuyerSkuConverter.toModelList(productSkus);
                List<BuyerProductSkuMerged> skuMergeds = new ArrayList<>();
                buyerProductSkus.forEach(sku -> {
                    BuyerProductSkuMerged skuMerged = baseBuyerSkuConverter.toMergedModel(sku);
                    skuMerged.setEditTime(DateUtil.date());
                    skuMerged.setCreateTime(DateUtil.date());
                    skuMergeds.add(skuMerged);
                });

                StoreProductCrmebRequest storeProductCrmebRequest = sourceBuyerProductUtil.buildCrmebProduct(buyerProduct, skuMergeds, Constants.RATE_BUYER_2_CRMEB_FLOAT, Constants.RATE_BUYER_2_CRMEB, Constants.RATE_BUYER_2_CRMEB_COST);
                saveCrmebProduct(storeProductCrmebRequest, storeProduct, stock);
            // 欧洲商品
            } else if (ProductTypeEnum.valueOf(storeProduct.getIsEurope()) == ProductTypeEnum.EUROPE) {
                EuropeProduct europeProduct = europeProductUtil.getEuropeByBarCode(barCode);
                // 没有查询到商品
                if (null == europeProduct || CollectionUtils.isEmpty(europeProduct.getSkuList())) {
                    // log.info("--------------- 实时查询europe商品, 未取到数据, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                // 金额或者库存不对
                if (1 != europeProduct.getPrice().compareTo(BigDecimal.ZERO) || 0 >= europeProduct.getStock()) {
                    // log.info("--------------- 实时查询buyer商品, 商品金额不是正常值, 直接下架并返回, 商品barCode: {}---------------", barCode);
                    soldOut(storeProduct.getId());
                    return barCode;
                }
                List<EuropeBrand> europeBrands = europeBrandService.list();
                Map<String, EuropeBrand> europeBrandMap = new HashMap<>();
                for(EuropeBrand europeBrand : europeBrands) {
                    europeBrandMap.put(europeBrand.getBrandName().toLowerCase(), europeBrand);
                }
                StoreProductCrmebRequest storeProductCrmebRequest = sourceEuropeProductUtil.buildEuropeProduct(europeProduct, europeBrandMap, Constants.RATE_EUROPE_2_CRMEB_FLOAT, Constants.RATE_EUROPE_2_CRMEB, Constants.RATE_EUROPE_2_CRMEB_COST);
                saveCrmebProduct(storeProductCrmebRequest, storeProduct, storeProductCrmebRequest.getStock());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }

    /**
     * 商品下架
     * @Description:  
     * @author daigb 
     * @param @param id
     * @return void
     * @throws
     */
    private void soldOut(Integer id) {
        storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate().eq(StoreProduct::getId, id).set(StoreProduct::getIsShow, 0));
    }

    private void saveCrmebProduct(StoreProductCrmebRequest storeProductCrmebRequest, StoreProduct storeProduct, Integer stock) {
        /****** 主表数据保存 *******/
        StoreProduct storeProductUpdate = new StoreProduct();
        BeanUtils.copyProperties(storeProductCrmebRequest, storeProductUpdate);
        storeProductUpdate.setStock(stock);
        storeProductUpdate.setUpdateFlag(true);
        boolean isUpdate = null != storeProduct;
        Integer productId = 0;
        String barCode = storeProductCrmebRequest.getBarCode();

        if (isUpdate) {
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getId, storeProduct.getId())
                    .set(StoreProduct::getPrice, storeProductUpdate.getPrice())
                    .set(null != storeProductUpdate.getPromotePrice(), StoreProduct::getPromotePrice, storeProductUpdate.getPromotePrice())
                    .set(null != storeProductUpdate.getVipPrice(), StoreProduct::getVipPrice, storeProductUpdate.getVipPrice())
                    .set(null != storeProductUpdate.getOtPrice(), StoreProduct::getOtPrice, storeProductUpdate.getOtPrice())
                    .set(null != storeProductUpdate.getPostage(), StoreProduct::getPostage, storeProductUpdate.getPostage())
                    .set(null != storeProductUpdate.getBrandId(), StoreProduct::getBrandId, storeProductUpdate.getBrandId())
                    .set(null != storeProductUpdate.getBrandName(), StoreProduct::getBrandName, storeProductUpdate.getBrandName())
                    .set(null != storeProductUpdate.getGiveIntegral(), StoreProduct::getGiveIntegral, storeProductUpdate.getGiveIntegral())
                    .set(null != storeProductUpdate.getCost(), StoreProduct::getCost, storeProductUpdate.getCost())
                    .set(null != storeProductUpdate.getSourceCost(), StoreProduct::getSourceCost, storeProductUpdate.getSourceCost())
                    .set(null != storeProductUpdate.getSpecType(), StoreProduct::getSpecType, storeProductUpdate.getSpecType())
                    .set(null != storeProductUpdate.getCreateTime(), StoreProduct::getCreateTime, storeProductUpdate.getCreateTime())
                    .set(null != storeProductUpdate.getLastPushTime(), StoreProduct::getLastPushTime, storeProductUpdate.getLastPushTime())
//                    .set(null != storeProductUpdate.getIsEurope(), StoreProduct::getIsEurope, storeProductUpdate.getIsEurope())
                    .set(StoreProduct::getIsShow, true)
                    .set(StoreProduct::getStock, stock)
                    );
            productId = storeProduct.getId();
            barCode = storeProduct.getBarCode();
        } else {
            storeProductService.save(storeProductUpdate);
            productId = storeProductUpdate.getId();
        }
        /****** attr表保存 ********/
        if (isUpdate) {
            storeProductAttrService.removeByProductId(productId);
        }
        List<StoreProductAttr> attrs = storeProductCrmebRequest.getAttr();
        for (StoreProductAttr attr : attrs) {
            attr.setProductId(productId);
            attr.setBarCode(barCode);
            attr.setAttrValues(StringUtils.strip(attr.getAttrValues().replace("\"", ""), "[]"));
        }
        storeProductAttrService.saveBatch(attrs);
        /****** value表保存 *********/
//        Map<String, StoreProductAttrValue> dbStoreProductAttrValueMap = new HashMap<>();
        if (isUpdate) {
//            List<StoreProductAttrValue> dbStoreProductAttrValues = storeProductAttrValueService.list(Wrappers.<StoreProductAttrValue>lambdaQuery().eq(StoreProductAttrValue::getProductId, productId));
//            dbStoreProductAttrValueMap = dbStoreProductAttrValues.stream().collect(Collectors.toMap(StoreProductAttrValue::getSourceSkuId, s -> s, (value1, value2) -> {
//                return value1;
//            }));
            // 删除所有value
            storeProductAttrValueService.removeByProductId(productId);
        }
        List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = storeProductCrmebRequest.getAttrValue();
        List<StoreProductAttrValue> values = new ArrayList<>();
        for (StoreProductAttrValueRequest attrValuesRequest : storeProductAttrValuesRequest) {
            attrValuesRequest.setProductId(productId);
            attrValuesRequest.setBarCode(barCode);
            StoreProductAttrValue spav = new StoreProductAttrValue();
            BeanUtils.copyProperties(attrValuesRequest, spav);
            List<String> skuList = new ArrayList<>();
            for (Map.Entry<String, String> vo : attrValuesRequest.getAttrValue().entrySet()) {
                skuList.add(vo.getValue());
                spav.setSuk(String.join(",", skuList));
            }
            spav.setAttrValue(JSON.toJSONString(attrValuesRequest.getAttrValue()));
//            StoreProductAttrValue tempValue = dbStoreProductAttrValueMap.get(spav.getSourceSkuId());
//            if (null != tempValue) {
//                spav.setId(tempValue.getId());
//            }
            values.add(spav);
        }
        storeProductAttrValueService.saveBatch(values);
        /****** result表保存 ******/
        if (isUpdate) {
            storeProductAttrResultService.remove(Wrappers.<StoreProductAttrResult>lambdaQuery().eq(StoreProductAttrResult::getProductId, productId));
        }
        StoreProductAttrResult attrResult = new StoreProductAttrResult(/*0, */productId, systemAttachmentService.clearPrefix(JSON.toJSONString(storeProductCrmebRequest.getAttrValue())), Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000L)), Constants.PRODUCT_TYPE_NORMAL, barCode);
        storeProductAttrResultService.save(attrResult);

        // 处理富文本
        StoreProductDescription dbDescription = storeProductDescriptionService.getOne(Wrappers.<StoreProductDescription>lambdaQuery()
        		.eq(StoreProductDescription :: getProductId, storeProductUpdate.getId())
        		.last("LIMIT 1")
        		);
        StoreProductDescription storeProductDescription = StoreProductDescription.getDescriptionByProduct(storeProductUpdate);
        storeProductDescription.setId(ObjectUtil.isNotNull(dbDescription) ? dbDescription.getId() : null);
        storeProductDescription.setProductId(storeProductUpdate.getId());
        storeProductDescriptionService.saveOrUpdate(storeProductDescription);
    }

}
